package org.fixies.spreadsheet.interpreter;

import org.fixies.spreadsheet.Section;
import org.fixies.spreadsheet.Unit;
import org.fixies.utils.Validator;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * // TODO change this
 * User: Tsuyoshi
 * Date: 2010/11/03
 * Time: 21:13:01
 */
public class SectionNode {

    /** セクションを表す表現 */  
    public static final String SECTION_EXPRESSION = "#SECTION=";

    /** ユニットノード */
    private List<UnitNode> unitNodes_ = new ArrayList<UnitNode>();

    /** ID */
    private String sectionId_ = "";

    /** 起源 */
    private String origin_;

    /** コンストラクタ */
    public SectionNode(String origin) {
        origin_ = origin;
    }

    /**
     * 評価する。
     * @param context コンテキスト
     */
    public void evaluate(SheetContext context) {
        // 空行を除く先頭行を取得する
        String[] line = context.currentSkippingEmptyRow();
        // セクション定義に到達したらセクション名を取得
        if (isSection(line)) {
            sectionId_ = getSectionName(line);
            line = context.nextSkippingEmptyRow();
        }
        
        while (line != null) {
            if (isSection(line)) {
                break;   // 次のセクションに到達したら修了
            } else {
                UnitNode unitNode = new UnitNode(origin_);
                unitNode.evaluate(context);
                unitNodes_.add(unitNode);
            }
            line = context.nextSkippingEmptyRow();
        }
    }

    /**
     * 解析結果を取得する。
     * @return 解析結果
     */
    public Section getResult() {
        return new Section(sectionId_, createUnits(unitNodes_), origin_);
    }

    /**
     * ユニットを生成する。
     * @param unitNodes ユニットノード
     * @return このセクションに含まれるユニット群
     */
    private Map<String, Unit> createUnits(List<UnitNode> unitNodes) {
        Map<String, Unit> units = new HashMap<String, Unit>();
        for (UnitNode unitNode : unitNodes) {
            Unit unit = unitNode.getResult();
            units.put(unit.getId(), unit);
        }
        return units;
    }


    private boolean isSection(String[] line) {
        return !Validator.isNullOrEmpty(line) && line[0].startsWith(SECTION_EXPRESSION);
    }

    private String getSectionName(String[] line) {
        return line[0].split("=")[1];
    }

}
